/**
 * @description 
 * 
 * Copyright (c) 2015-2017 chengxin,Inc.All Rights Reserved.
 */
package com.vcredit.creditcat.manager.product;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.alibaba.dubbo.config.annotation.Service;
import com.fasterxml.jackson.core.type.TypeReference;
import com.vcredit.creditcat.api.ICustProductApplyTaskManager;
import com.vcredit.creditcat.enumtype.SmsDescEnum;
import com.vcredit.creditcat.enumtype.hl.ProductScheduleEnum;
import com.vcredit.creditcat.manager.SMSMessageManager;
import com.vcredit.creditcat.model.AuthIdentity;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.model.CustAccount;
import com.vcredit.creditcat.model.CustProductApply;
import com.vcredit.creditcat.service.AuthIdentityService;
import com.vcredit.creditcat.service.CustAccountService;
import com.vcredit.creditcat.service.CustProductApplyService;
import com.vcredit.creditcat.service.CustService;
import com.vcredit.creditcat.util.ConcurrentDateUtil;
import com.vcredit.creditcat.util.RSAUtil;
import com.vcredit.creditcat.vo.product.hl.HlReturnInfoVo;
import com.vcredit.framework.util.HttpRequest;
import com.vcredit.framework.util.JacksonUtil;

@Service(protocol = { "protocol1" }, version = "1.0")
public class CreditProductApplyTaskManager implements ICustProductApplyTaskManager {

	@Value("${resource.soft.url}")
	private String imagUrl;

	// 对接所用url
	@Value("${product.hl.url}")
	private String creditHLUrl;
	// 公钥
	@Value("${xinyongmao.publicKey}")
	private String publicKey;
	// 私钥
	@Value("${xinyongmao.privateKey}")
	private String privateKey;
	@Autowired
	private CustProductApplyService custProductApplyService;
	@Autowired
	public SMSMessageManager sMSMessageManager;
	@Autowired
	private AuthIdentityService authIdentityService;
	@Autowired
	private CustService custService;
	@Autowired
	private CustAccountService custAccountService;
	private static Logger logger = LoggerFactory.getLogger(CreditProductApplyTaskManager.class);
	// 参数定义
	private static final String successStatus = "1";
	private static final String refuseStatus = "0";
	private static final String errStatus = "-1";
	private static final int dealingStatus = 2;
	private static final String productType = "XYM";

	@Override
	public void commit() throws Exception {
		// TODO Auto-generated method stub
		logger.info("开始循环贷款项目！！");
		CustProductApply custProductApply = new CustProductApply();

		// 产品id
		custProductApply.setProductId(Long.parseLong(ProductScheduleEnum.HL.getProductId()));
		custProductApply.setAuditResult(2);
		HlReturnInfoVo result = new HlReturnInfoVo();
		try {
			List<CustProductApply> list = custProductApplyService.findByConditions(custProductApply);
			logger.info("有" + list.size() + "个产品需要拉取！");
			// 循环拉取
			if (list.size() > 0) {
				for (CustProductApply custProductApply2 : list) {
					Cust cust = custService.findById(custProductApply2.getCustId());
					result = this.grantQuery(this.getProductCheckCreditParam(cust));
					CustProductApply apply = this.getSaveAuditResultParam(result);
					if (dealingStatus != apply.getAuditResult()) {

						apply.setApplyId(custProductApply2.getApplyId());
						custProductApplyService.update(apply);
						try { // 发送成功或失败短信，不影响主流程
							CustAccount account = new CustAccount();
							account.setCustId(cust.getCustId());

							CustAccount custAccount = custAccountService.find(account).get(0);
							String mobile = custAccount.getUserName();
							String appdesc = custAccount.getAppDesc().split(";")[0].toString();;
							String productName = SmsDescEnum.getNameByAppDesc(appdesc);
							String userName = custAccount.getAccountRealname();

							if (apply.getAuditResult() == 1) {
								sMSMessageManager.sendCreditSuccess(mobile, productName, userName);
							} else if (apply.getAuditResult() == 0) {
								sMSMessageManager.sendCreditFail(mobile, productName, userName);
							}
						} catch (Exception e) {

						}

					} else {
						if (StringUtils.isNotBlank(custProductApply2.getAuditTime())) {
							String date = custProductApply2.getAuditTime();
							long dayDiff = ConcurrentDateUtil.dayDiffPlusOne(ConcurrentDateUtil.formatDateTime(ConcurrentDateUtil.addDayTime(ConcurrentDateUtil.strToDate(date), 7)));

							// 判断当前时间是否是大于申请时间 7天计算
							if (dayDiff >= 0) {
								apply.setApplyId(custProductApply2.getApplyId());
								apply.setAuditResult(0);
								apply.setRejectMsg("7天未拿到结果自动拒绝");
								custProductApplyService.update(apply);
							}

						}
					}
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			logger.error("还乐拉取账单失败~！", e.getMessage());
		}
	}

	/**
	 * 授信结果查询
	 * 
	 * @param submitDto
	 * @return
	 * @throws Exception
	 */
	public HlReturnInfoVo grantQuery(Object submitDto) throws Exception {
		HlReturnInfoVo authPersonal = new HlReturnInfoVo();
		try {
			logger.info(creditHLUrl.concat("customer/queryCustomerCredit"));
			String json = JacksonUtil.Obj2Json(submitDto);
			logger.info("还乐查询额度请求json:" + json);
			String sa = this.encodeJsonParam(json);
			String resultJson = HttpRequest.doJson(creditHLUrl.concat("customer/queryCustomerCredit"), sa);
			String decodeJsonParam = this.decodeJsonParam(resultJson);
			authPersonal = JacksonUtil.Json2Obj(decodeJsonParam, new TypeReference<HlReturnInfoVo>() {
			});
			logger.info("还乐查询额度转换结果:" + JacksonUtil.Obj2Json(authPersonal));
		} catch (Exception e) {
			logger.error("还乐定时查询额度失败：", e);
		}
		return authPersonal;
	}

	private String encodeJsonParam(String jsonParam) throws UnsupportedEncodingException, Exception {
		// 加密
		String requestContentBase64 = Base64.encodeBase64String(RSAUtil.encryptByPrivateKey(jsonParam.getBytes("utf-8"), this.privateKey));
		return requestContentBase64;
	}

	private String decodeJsonParam(String respJson) throws Exception {
		String result = "";
		// 解密
		byte[] res = RSAUtil.decryptBASE64(respJson);
		result = new String(RSAUtil.decryptByPublicKey(res, this.publicKey));
		return result;
	}

	/**
	 * 封装返回实体类
	 * 
	 * @param input
	 * @return
	 * @throws Exception
	 */
	public CustProductApply getSaveAuditResultParam(HlReturnInfoVo input) throws Exception {
		CustProductApply custProductApply = new CustProductApply();

		// 拒绝
		if (refuseStatus.equals(input.getStatus())) {
			custProductApply.setAuditTime(ConcurrentDateUtil.formatDateTime(new Date()));

			custProductApply.setRejectMsg(input.getMsg());
			custProductApply.setSuggestion("");
			custProductApply.setCreditAmt(0);
			custProductApply.setIsApply(false);
			custProductApply.setAuditResult(0);
			custProductApply.setCreditApplyTime(ConcurrentDateUtil.formatDateTime(ConcurrentDateUtil.addDayTime(new Date(), 30)));
			return custProductApply;
		}
		// 成功返回
		if (successStatus.equals(input.getStatus())) {
			custProductApply.setAuditTime(ConcurrentDateUtil.formatDateTime(new Date()));
			custProductApply.setRejectMsg(input.getMsg());
			custProductApply.setCreditExpiretime(input.getContent().getExpire_date());
			custProductApply.setIsApply(false);
			BigDecimal bigdes = new BigDecimal(input.getContent().getTotalRate());
			custProductApply.setTotalServiceRate(bigdes);
			String amount = input.getContent().getAmount();
			int creditAmt = Integer.parseInt(amount.substring(0, amount.indexOf(".")));
			custProductApply.setCreditAmt(100 * creditAmt);
			custProductApply.setAuditResult(1);
		}
		if (errStatus.equals(input.getStatus())) {
			custProductApply.setAuditResult(2);
		}
		return custProductApply;
	}

	/**
	 * 封装拉取信息
	 * 
	 * @param cust
	 * @return
	 */
	public Object getProductCheckCreditParam(Cust cust) throws Exception {
		Long lastProccessId = cust.getLastProccessId();

		AuthIdentity identity = authIdentityService.findByProcessId(lastProccessId);

		Map<String, String> map = new HashMap<>();
		map.put("identityNo", identity.getCitizenId());// 身份证号
		// map.put("userName", identity.getName());// 用户姓名
		// map.put("facePairResult", identity.getLiveCompareValue() + "");//
		// 活体分值(新增参数)
		map.put("productType", productType);// 产品类型(固定XYM)
		return map;
	}
}
